<?php

namespace app\components;

// use phpDocumentor\Reflection\DocBlock\Tags\Var_;

use phpDocumentor\Reflection\DocBlock\Tags\Var_;

use yii;
use yii\base\ErrorException;
use app\components\Api;
use app\components\Log;
use yii\web\ServerErrorHttpException;

/**
 * all loyalty api config and functions
 */
class Loyalty
{
    /**
     * return the loyalty api basic config parameters
     * @return array or string
     */
    public static function config($config = null)
    {         
        // 获取DMS返回的Loyalty Config
        $session = Yii::$app->session;
        if ($session->has('loyaltyConfig')) {
            $loyaltyConfig = $session->get('loyaltyConfig');
        } else {
            // ------------------------------------------------------------------
            // Get Loyalty Config by appid and access_token
            // ------------------------------------------------------------------
            // https://proxcrm.xgate.com/front/index.php/site/getTenantWechatConfig?tenantId=[tenantId]&appid=[appId]&accesstoken=[accessToken]
            // @method Get
            // @author Raymond NG
            // https://dev.xgate.com/issues/3568?tab=history_comments
            $appid = Wechat::config('appid');
            $access_token = Wechat::config('access_token');
            $url = 'https://proxcrm.xgate.com/front/index.php/site/getTenantWechatConfig?tenantId=[tenantId]&appid=' . $appid . '&accesstoken=' . $access_token;
            $re = Api::get($url);
            $loyaltyConfig = Api::parseJSON($re);
            // 验证
            if (empty($loyaltyConfig['loyalty_url']) || empty($loyaltyConfig['tenant_id']) || empty($loyaltyConfig['loyalty_accountid']) || empty($loyaltyConfig['loyalty_username']) || empty($loyaltyConfig['loyalty_password'])) {
                throw new ServerErrorHttpException('Loyalty Config Params Not Found.');
            }

            // 验证url
            // $loyalty_url = 'http://202.177.204.24/';
            // if (filter_var($loyalty_url, FILTER_VALIDATE_URL) === false) {
            //     throw new ServerErrorHttpException('Error: the loyalty api url [' . $loyalty_url . '] is not validate');
            // }

            // 缓存
            $session->set('loyaltyConfig', $loyaltyConfig);
        }
        
        // 昊祥
        // $loyalty_accountid = 'XGChengDu2';
        // $loyalty_username = 'developer@chengdu2.xgate.com';
        // $loyalty_password = 'cddev1234';

        // momo
//         $loyalty_accountid = 'momoadmin';
//         $loyalty_username = 'admin@chengdu.momo.com';
//         $loyalty_password = 'cdmomo19127';

        // 新华文轩
        // $loyalty_accountid = 'winshare';
        // $loyalty_username = 'admin@winshare.com';
        // $loyalty_password = 'winsh5346';

        // JSelect
        // $loyalty_accountid = 'JSelect';
        // $loyalty_username = 'admin@chn.jselect.com';
        // $loyalty_password = '59jfl438fc';
//         $loyaltyConfig['loyalty_url'] = 'http://202.177.204.24/';
		//原代码
        $configs = [
            'loyalty_url' => $loyaltyConfig['loyalty_url'],
            'authentication' => [
                'account_id' => $loyaltyConfig['loyalty_accountid'],
                'username' => $loyaltyConfig['loyalty_username'],
                'password' => $loyaltyConfig['loyalty_password'],
            ],
            'tenant_id' => $loyaltyConfig['tenant_id'],
        ];

        //先写死便于开发
		
        //正式
//         $loyaltyConfig['loyalty_url'] = 'http://loyaltyapi.xgate.com/w1/api/index.php/';
//         $loyaltyConfig['loyalty_accountid'] = 'JSelect';
//         $loyaltyConfig['loyalty_username'] = 'admin@chn.jselect.com';
//         $loyaltyConfig['loyalty_password'] = '59jfl438fc';
        
//         测试
//         $loyaltyConfig['loyalty_url'] = 'http://loyalty-uat.xgate.com:8080/index.php';
//         $loyaltyConfig['loyalty_accountid'] = 'demo';
//         $loyaltyConfig['loyalty_username'] = 'admin@chn.jselect.com';
//         $loyaltyConfig['loyalty_password'] = 'xg1234';
//         echo "<pre/>";
//         var_dump($configs);die;
// //         Log::debug("configs", $configs);
        return is_null($config) ? $configs : $configs[$config];
    }

    /**
     * magic static call loyalty api
     */
    public static function __callStatic($name, $arguments)
    {
        // 检查Call的方法是否在API Maps
        $apiMap = static::apiMap();
        if (!array_key_exists($name, $apiMap)) {
            throw new ServerErrorHttpException('Error: the static method [ Loyalty::' . $name . '() ] don`t exists.');
        } else {
            $api = $apiMap[$name];
        }

        // 如果不需要传post字段，则allowEmpty为true
        if (isset($api['allowEmpty']) && $api['allowEmpty'] == true) {
            $validate_result = true;
            if (empty($arguments[0])) {
                $data = [];
            } else {
                $data = $arguments[0];
            }
        } else {
            // 如果是post请求，需要验证post字段是否正确
            if ($api['method'] == 'post') {
                $validate_result = static::validate($api, $arguments);
                $data = $arguments[0];
            } else {
                // get请求
                $validate_result = true;
                $data = [];
            }
        }

        // 执行API Call
        if ($validate_result === true) {
            return static::call($api, $data);
        }
    }

    /**
     * validate the params
     * @param string $api
     * @param array $data
     * @return string $param or boolean true
     */
    public static function validate($api, $arguments)
    {
        if (empty($arguments[0])) {
            throw new ServerErrorHttpException('Error: post data is **empty** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
        }
        $data = $arguments[0];

        $params = $api['params'];

        // build a new array without "*"
        $match = [];
        foreach ($params as $param) {
            $default_param = strstr($param, '*', true);
            if ($default_param !== false) {
                $match[] = $default_param;
            } else {
                $match[] = $param;
            }
        }

        // validate the data unavailable parameter and null parameter
        foreach ($data as $key => $value) {
            if (!in_array($key, $match)) {
                throw new ServerErrorHttpException('Error: the param: [' . $key . '] is **unavailable** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
            }
            if ($value === null || $value === false) {
                throw new ServerErrorHttpException('Error: the param: [' . $key . '] is **null** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
            }
        }

        // validate the reuired parameter
        foreach ($params as $param) {
            $param = strstr($param, '*', true);
            if ($param !== false) {
                if (empty($data[$param])) {
                    throw new ServerErrorHttpException('Error: the param: [' . $param . '] is **required** when call [ Loyalty::' . $api['controller'] . '_' . $api['action'] . '() ].');
                }
            }
        }

        return true;
    }

    /**
     * use Api component call loyalty api
     * @param array $api
     * @param array | null $data
     */
    public static function call($api, $data)
    {
        $configs = static::config();
        
        $data = array_merge($data, $configs['authentication']);
        // 判断连接的最后是否带 "/"
        if (substr($configs['loyalty_url'], -1) == '/') {
            $url = $configs['loyalty_url'] . $api['controller'] . '/' . $api['action'];
        } else {
            $url = $configs['loyalty_url'] . '/' . $api['controller'] . '/' . $api['action'];
        }

        if ($api['method'] == 'post') {
            $re = Api::post($url, $data);            
        } else {
            $re = Api::get($url);
        }
        
        if ($re) {
            $re = Api::parseJSON($re);
        } else {
            $re = false;
        }
//         echo '<pre>'; print_r($re);die;
        return $re;        
        // 自行在业务流程中判断Api的返回结果
        // 不抛出错误，因为业务流程中我们需要在报错信息
        // if (isset($re['status']) && $re['status'] == 'error') {
            // throw new ServerErrorHttpException('Loyalty API Error, Error msg: [' . $re['message'] . '], When call [' . $url . ']');
        // } else {
            // return $re;
        // }
    }

    /**
     * loyalty api map
     * 必填参数在后面加上*
     * 如果没有post参数，则添加 'allowEmpty' => true
     */
    public static function apiMap()
    {
        $apiMap = [
            'customer_search' => [
                'controller' => 'customer',
                'action' => 'search',
                'method' => 'post',
                'params' => ['mobile', 'code', 'first_name', 'last_name', 'email', 'phone', 'wechat_openid', 'mobilePhone'],
                'allowEmpty' => true,
            ],
            'customer_get' => [
                'controller' => 'customer',
                'action' => 'get',
                'method' => 'post',
                'params' => ['code', 'email', 'wechat_openid', 'mobile', 'card_number'],
            ],
            'customer_balance' => [
                'controller' => 'customer',
                'action' => 'customer_balance',
                'method' => 'post',
                'params' => ['campaign_id*', 'code*', 'card_number'],
            ],
            'customer_create' => [
                'controller' => 'customer',
                'action' => 'create',
                'method' => 'post',
                'params' => ['code*', 'card_number', 'first_name', 'last_name', 'mobile', 'phone', 'email', 'birth_yyyy', 'birth_mm', 'birth_dd', 'address1', 'wechat_openid', 'gender', 'title'],
            ],
            'customer_update' => [
                'controller' => 'customer',
                'action' => 'update',
                'method' => 'post',
                'params' => ['code*', 'card_number', 'wechat_openid','first_name', 'city', 'state', 'district', 'agegroup', 'last_name', 'email', 'birthday', 'mobile', 'phone', 'gender', 'address1', 'address2', 'address3', 'output', 'wechat_openid', 'birth_yyyy', 'birth_mm', 'birth_dd', 'period_grade_id', 'title'],
            ],
            'customer_tnx_detail' => [
                'controller' => 'customer',
                'action' => 'gettransactionbycampaign',
                'method' => 'post',
                'params' => ['campaign_id*', 'code*', 'pagesize*', 'pageno*', 'type'],
            ],
            'campaign_new' => [
                'controller' => 'campaign',
                'action' => 'new_campaign',
                'method' => 'post',
                'params' => ['campaign_type', 'campaign_name', 'campaign_name_c', 'points_ratio', 'output'],
            ],
            'campaign_list' => [
                'controller' => 'campaign',
                'action' => 'list_campaigns',
                'method' => 'post',
                'params' => [],
                'allowEmpty' => true,
            ],
            'create_pointrule' => [
	            'controller' => 'campaign',
	            'action' => 'create_point_rule',
	            'method' => 'post',
	            'params' => ['campaign_id*', 'type*', 'value*', 'level*', 'description*'],
            ],
            'update_pointrule' => [
	            'controller' => 'campaign',
	            'action' => 'update_point_rule',
	            'method' => 'post',
	            'params' => ['campaign_id*', 'pointrule_id*', 'type', 'value', 'level', 'description'],
            ],
            'list_point_rule' => [
	            'controller' => 'campaign',
	            'action' => 'List_point_rule',
	            'method' => 'post',
	            'params' => ['campaign_id', 'id'],
	            'allowEmpty' => true,
            ],
            'create_depreciation' => [
	            'controller' => 'campaign',
	            'action' => 'Create_depreciation',
	            'method' => 'post',
	            'params' => ['campaign_id*', 'depreciation_type*','depreciation_interval*', 'depreciation_interval_type', 'depreciation_percentage'],
	        ],
            'campaign_delete' => [
	            'controller' => 'campaign',
	            'action' => 'delete_campaign',
	            'method' => 'post',
	            'params' => ['campaign_id*'],
            ],
            'coupon_list' => [
                'controller' => 'coupon',
                'action' => 'getCoupon',
                'method' => 'post',
                'params' => ['campaign_id*', 'customer_id', 'code', 'card_number', 'detail'],
            ],
            'coupon_detail' => [
                'controller' => 'coupon',
                'action' => 'getCouponGroup',
                'method' => 'post',
                'params' => ['campaign_id*', 'coupongroup_id', 'identifier'],
            ],          
            'coupon_create' => [
	            'controller' => 'coupon',
	            'action' => 'create_coupon',
	            'method' => 'post',
	            'params' => ['name', 'autocreate', 'code_pattern', 'barcode_pattern', 'barcode', 'name_c', 'description', 'identifier', 'description_c', 'terms', 'store_id', 'terms_c', 'thumbnail_url', 'campaign_id', 'category', 'category_c', 'store_code', 'number_of_coupons', 'usage_limit', 'brand', 'brand_c','conditions','conditions_c', 'start_date', 'end_date', 'type'],
            ],
            'coupon_update' => [
	            'controller' => 'coupon',
	            'action' => 'update_coupon',
	            'method' => 'post',
	            'params' => ['campaign_id*', 'brand', 'serial', 'code_pattern', 'identifier', 'barcode_pattern', 'barcode', 'limit_by', 'autocreate','description_c', 'auto_create', 'coupon_id*', 'store_id' ,'thumbnail_url', 'number_of_coupons', 'usage_limit', 'name', 'description', 'identifier', 'category', 'type', 'coupongroup_id', 'start_date', 'end_date', 'terms'],
            ],
            'list_coupon' => [
	            'controller' => 'coupon',
	            'action' => 'list_coupon',
	            'method' => 'post',
	            'params' => ['campaign_id', 'category', 'coupon_id', 'brand'],
	            'allowEmpty' => true,
            ],
            'customer_delete' => [
                'controller' => 'customer',
                'action' => 'delete',
                'method' => 'post',
                'params' => ['code*', 'limit'],
            ],
            'login' => [
                'controller' => 'customer',
                'action' => 'login',
                'method' => 'post',
                'params' => ['username*', 'password'],
            ],
            'transaction_record' => [
                'controller' => 'transaction',
                'action' => 'record',
                'method' => 'post',
                'params' => ['code*', 'transaction_datetime*', 'amount*', 'campaign_id*']
            ],
            'transaction_delete' => [
                'controller' => 'transaction',
                'action' => 'delete',
                'method' => 'post',
                'params' => ['code*', 'invoiceno', 'campaign_id*']
            ],
            'transaction_redeem' => [
                'controller' => 'transaction',
                'action' => 'redeem',
                'method' => 'post',
                'params' => ['code*', 'points_to_redeem', 'campaign_id*']
            ],
            'store_create' => [
	            'controller' => 'store',
	            'action' => 'create',
	            'method' => 'post',
	            'params' => ['code*', 'storename', 'store_username', 'store_password', 'redeem_password', 'address1'],
            ],
            'store_list' => [
	            'controller' => 'store',
	            'action' => 'list',
	            'method' => 'post',
	            'params' => ['code', 'email', 'storename', 'phone', 'store_username'],
	            'allowEmpty' => true,
            ],
            'store_update' => [
	            'controller' => 'store',
	            'action' => 'update',
	            'method' => 'post',
	            'params' => ['code*', 'email', 'storename', 'phone', 'store_username', 'store_password','redeem_password','address1', 'address2', 'address3', 'desc1', 'desc2', 'allowlogin'],
            ],
            'store_get' => [
	            'controller' => 'store',
	            'action' => 'get',
	            'method' => 'post',
	            'params' => ['code', 'email', 'storename', 'phone', 'store_username'],
	            'allowEmpty' => true
            ],
            'field_config' => [
	            'controller' => 'account',
	            'action' => 'config',
	            'method' => 'post',
	            'params' => [],
	            'allowEmpty' => true,
            ],
            'update_global' => [
	            'controller' => 'account',
	            'action' => 'updateGlobalConfig',
	            'method' => 'post',
	            'params' => ['config*','name*'],
	            'allowEmpty' => true,
            ],
            'create_model' => [
	            'controller' => 'account',
	            'action' => 'createModelConfig',
	            'method' => 'post',
	            'params' => ['model*','scenario*','config*'],
	            'allowEmpty' => true,
            ],
            //查询api参数
            'generator' => [
	            'controller' => 'support',
	            'action' => 'getFields',
	            'method' => 'post',
	            'params' => ['hash*'],
            ],
            'list_earnrule' => [
	            'controller' => 'campaign',
	            'action' => 'list_earnrule',
	            'method' => 'post',
	            'params' => ['earnrule_id', 'coupon_id'],
	            'allowEmpty' => true,
            ],
            'earnrule_create' => [
	            'controller' => 'campaign',
	            'action' => 'create_earnrule',
	            'method' => 'post',
	            'params' => ['campaign_id*', 'event', 'active*', 'limit_per_customer','description*', 'activity_rule', 'trigger_on', 'txn_amount'],
            ],
            'update_earnrule' => [
	            'controller' => 'campaign',
	            'action' => 'update_earnrule',
	            'method' => 'post',
	            'params' => ['earnrule_id*', 'trigger_on', 'limit_per_customer', 'conditions', 'active', 'tnx_amount'],
            ],
            'trigger_earnrule' => [
	            'controller' => 'campaign',
	            'action' => 'trigger_earnrule',
	            'method' => 'post',
	            'params' => ['event*', 'code*', 'event_key'],
            ],
            'remove_rule_from_item' => [
	            'controller' => 'campaign',
	            'action' => 'remove_earnrule_from_item',
	            'method' => 'post',
	            'params' => ['earnrule_id*', 'coupon_id*'],
            ],
            'add_rule_to_item' => [
	            'controller' => 'campaign',
	            'action' => 'add_earnrule_to_item',
	            'method' => 'post',
	            'params' => ['earnrule_id*', 'coupon_id*', 'reward_qty', 'validtime', 'unit', 'pointrule_id'],
            ],
            'get_coupon_codes' => [
	            'controller' => 'coupon',
	            'action' => 'get_coupon_codes',
	            'method' => 'post',
	            'params' => ['campaign_id', 'limit', 'offset', 'code', 'summery', 'status', 'customer_id', 'coupon_id'],
            ],
            'coupon_list' => [
	            'controller' => 'coupon',
	            'action' => 'getCoupon',
	            'method' => 'post',
	            'params' => ['campaign_id', 'code', 'card_number', 'detail', 'status'],
            ],
            'coupon_redeem' => [
	            'controller' => 'coupon',
	            'action' => 'redeem',
	            'method' => 'post',
	            'params' => ['coupon_code*', 'redeem_password*'],
            ],
            'apply_reward' => [
	            'controller' => 'reward',
	            'action' => 'applyReward',
	            'method' => 'post',
	            'params' => ['code*', 'reward_identifier*'],
            ],
            'get_list' => [
	            'controller' => 'support',
	            'action' => 'getHashList',
	            'method' => 'post',
	            'params' => [],
	            'allowEmpty' => true,
            ],
            'coupon_generate_codes' => [
	            'controller' => 'coupon',
	            'action' => 'generate_codes',
	            'method' => 'post',
	            'params' => ['generate_num','coupon_id','identifier'],
            ],
        ];
        
        return $apiMap;
    }
}